package socket.Serveur;

import java.net.*;
import java.io.*;
import java.util.*;

//** Classe principale du serveur, gère les infos globales **
public class ServeurThread {

    private ArrayList<PrintStream>        tabClients = new ArrayList<PrintStream>(); // contiendra
                                                                                     // tous
                                                                                     // les
                                                                                     // flux
                                                                                     // de
                                                                                     // sortie
                                                                                     // vers
                                                                                     // les
                                                                                     // clients
    private int                           nbClients  = 0;                           // nombre
                                                                                     // total
                                                                                     // de
                                                                                     // clients
                                                                                     // connectés
    private LinkedHashMap<String, String> infos;

    private void initialize() {
        this.infos = new LinkedHashMap<String, String>();
        this.infos.put("Bidule", "Duponchelle");
        this.infos.put("Machin", "Oliva");
        this.infos.put("Truc", "Jeddi");
        this.infos.put("Chose", "Mnémoi");
        this.infos.put("Boulet", "Jeddi");
        this.infos.put("Gros boulet", "Jeddi");
    }

    public String addInfo(String surnom, String nom) {
        return this.infos.put(surnom, nom);
    }

    public LinkedHashMap<String, String> getInfos() {
        return this.infos;
    }

    // ** Methode : la première méthode exécutée, elle attend les connections **
    public static void main(String args[]) {
        ServeurThread serveur = new ServeurThread(); // instance de la classe
                                                     // principale
        serveur.initialize();
        try {
            Integer port = 2345;
            /*
             * if(args.length<=0) port=new Integer("18000"); // si pas
             * d'argument : port 18000 par défaut else port = new
             * Integer(args[0]); // sinon il s'agit du numéro de port passé en
             * argument
             */

            // new Commandes(blablaServ); // lance le thread de gestion des
            // commandes

            ServerSocket ss = new ServerSocket(port.intValue()); // ouverture
                                                                 // d'un socket
                                                                 // serveur sur
                                                                 // port
            // printWelcome(port);
            while (true) // attente en boucle de connexion (bloquant sur
                         // ss.accept)
            {
                new ClientThread(ss.accept(), serveur); // un client se
                                                        // connecte, un nouveau
                                                        // thread client est
                                                        // lancé
            }
        } catch (Exception e) {
        }
    }

    // ** Methode : envoie le message à tous les clients **
    synchronized public void sendAll(String message, String sLast) {
        for (PrintStream out : tabClients) // parcours de la table des connectés
        {
            if (out != null) // sécurité, l'élément ne doit pas être vide
            {
                // ecriture du texte passé en paramètre (et concaténation d'une
                // string de fin de chaine si besoin)
                out.println(message + sLast);
                // out.flush(); // envoi dans le flux de sortie
            }
        }
    }

    // ** Methode : détruit le client no i **
    synchronized public void delClient(int i) {
        nbClients--; // un client en moins ! snif
        if (tabClients.get(i) != null) // l'élément existe ...
        {
            tabClients.remove(i); // ... on le supprime
        }
    }

    // ** Methode : ajoute un nouveau client dans la liste **
    synchronized public int addClient(PrintStream out) {
        nbClients++; // un client en plus ! ouaaaih
        tabClients.add(out); // on ajoute le nouveau flux de sortie au tableau
        return tabClients.size() - 1; // on retourne le numéro du client ajouté
                                      // (size-1)
    }

    // ** Methode : retourne le nombre de clients connectés **
    synchronized public int getNbClients() {
        return nbClients; // retourne le nombre de clients connectés
    }

}